#include "tictactoewidget.h"

#include <QGridLayout>
#include <QSignalMapper>
#include <QDebug>

TicTacToeWidget::TicTacToeWidget(QWidget *parent)
{
    QGridLayout *gridLayout = new QGridLayout(this);
    QSignalMapper *mapper = new QSignalMapper(this);
    for(int row=0;row<3;++row)
    {
        for(int col=0;col<3;++col)
        {
            QPushButton* button = new QPushButton("");
            button->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
            gridLayout->addWidget(button,row,col);
            m_broad.append(button);
            mapper->setMapping(button,m_broad.size()-1);
            connect(button,SIGNAL(clicked()),mapper,SLOT(map()));   //当按键点击时，发送clicked消息，map接受消息
        }
    }
    connect(mapper,SIGNAL(mapped(int)),this,SLOT(HandleButtonClick(int)));  //当map接收到消息时，mapped将会发送，此时SLOT将会接受消息
}

TicTacToeWidget::~TicTacToeWidget()
{
    m_broad.clear();
}

void TicTacToeWidget::InitGame()
{
    for(QPushButton* button : m_broad)
    {
        button->setText("");
    }
    SetCurrentPlayer(Player::Player1);
    A.clear();
    B.clear();
    m_winCondition = {
        {0, 1, 2},
        {3, 4, 5},
        {6, 7, 8},
        {0, 3, 6},
        {1, 4, 7},
        {2, 5, 8},
        {0, 4, 8},
        {2, 4, 6}
    };
}

TicTacToeWidget::Player TicTacToeWidget::GetCurrentPlayer() const
{
    return m_currentPlayer;
}

void TicTacToeWidget::SetCurrentPlayer(const TicTacToeWidget::Player &p_player)
{
    if(p_player == m_currentPlayer)
        return;
    m_currentPlayer = p_player;
    emit CurrentPlayerChanged(p_player);
}

TicTacToeWidget::Player TicTacToeWidget::CheckWinCondition()
{
    auto set = GetCurrentPlayer() == Player::Player1 ? A : B;
    for(auto win : m_winCondition)
    {
        bool flag = true;
        for(auto pos : win)
        {
            if(!set.contains(pos))
            {
                flag = false;
                break;
            }
        }
        if(flag == true)
            return GetCurrentPlayer();
    }
    return Player::Invalid;
}

void TicTacToeWidget::HandleButtonClick(int index)
{
    if(m_currentPlayer == Player::Invalid)  //未开始
        return;
    if(index < 0 || index >= m_broad.size())    //越界
        return;
    QPushButton* button = m_broad[index];
    if(button->text()!="")      //有物体
        return;
    button->setText(GetCurrentPlayer()==Player::Player1?"X":"O");
    if(GetCurrentPlayer() == Player::Player1)
        A.insert(index);
    if(GetCurrentPlayer() == Player::Player2)
        B.insert(index);
    Player winner = CheckWinCondition();
    if(A.count()+B.count() == m_broad.size())
    {
        winner = Player::Draw;
    }
    if(winner == Player::Invalid)
    {
        SetCurrentPlayer(GetCurrentPlayer() == Player::Player1 ? Player::Player2 : Player::Player1);
        return;
    }else
    {
        emit GameOver(winner);
        m_currentPlayer = Player::Invalid;
    }
}


